package com.hui.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hui.dto.DeptInsertDTO;
import com.hui.dto.DeptPageDTO;
import com.hui.dto.DeptUpdateDTO;
import com.hui.entity.Dept;
import com.hui.excel.DeptExcel;
import com.hui.exception.IllegalParamException;
import com.hui.exception.ServerErrorException;
import com.hui.exception.VersionException;
import com.hui.mapper.DeptMapper;
import com.hui.service.DeptService;
import com.hui.vo.DeptVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@CacheConfig(cacheNames = "dept")
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @CacheEvict(allEntries = true)
    @Override
    public int insert(DeptInsertDTO dto) {
        String info = dto.getInfo();
        Dept dept = BeanUtil.copyProperties(dto, Dept.class);
        dept.setInfo(StrUtil.isBlank(info)?"暂无信息":info);
        dept.setCreated(LocalDateTime.now());
        dept.setUpdated(LocalDateTime.now());
        dept.setDeleted(0);
        dept.setVersion(0L);
        int result = deptMapper.insert(dept);
        if (result <= 0){
            throw new ServerErrorException("DB添加失败");
        }
        return result;
    }

    @Cacheable(key = "#p0",condition = "#p0 !=null", unless = "#result == null")
    @Override
    public Dept select(Long id) {
        Dept result = deptMapper.select(id);
        if (ObjectUtil.isNull(result)){
            throw new ServerErrorException("部门不存在");
        }
        return result;
    }

    @Cacheable(key = "#root.methodName", unless = "#result == null")
    @Override
    public List<DeptVO> list() {
        return deptMapper.list(new DeptPageDTO())
                .stream()
                .map(dept -> BeanUtil.copyProperties(dept, DeptVO.class))
                .collect(Collectors.toList());
    }

    @Cacheable(key = "#root.methodName+ ':' + #p0.toString() + ':' + #p0.getPageSize()", condition = "#p0 != null")
    @Override
    public PageInfo<Dept> page(DeptPageDTO dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        return new PageInfo<>(deptMapper.list(dto));
    }

    @CacheEvict(allEntries = true)
    @Transactional
    @Override
    @Retryable(value = VersionException.class)
    public int update(DeptUpdateDTO dto) {
        Long id = dto.getId();
        if (ObjectUtil.isNull(id)){
            throw new IllegalParamException("ID为空");
        }
        Dept dept = deptMapper.select(id);
        if (ObjectUtil.isNull(dept)){
            throw new ServerErrorException("记录不存在");
        }
        BeanUtil.copyProperties(dto, dept);
        dept.setUpdated(LocalDateTime.now());
        int result = deptMapper.update(dept);
        if (result <= 0){
            throw new VersionException("DB修改失败");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int delete(Long id) {
        int result = deptMapper.delete(id);
        if (result <= 0){
            throw new ServerErrorException("DB删除失败");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int deleteBatch(List<Long> ids) {
        int result = deptMapper.deleteBatch(ids);
        if (result <= 0){
            throw new ServerErrorException("DB删除失败");
        }
        return result;
    }



    @Override
    public List<DeptExcel> getExcelData() {
        return deptMapper.list(new DeptPageDTO())
                .stream()
                .map(dept -> {
                    DeptExcel deptExcel = BeanUtil.copyProperties(dept, DeptExcel.class);
                    if (ObjectUtil.isNotNull(dept.getRoom())){
                        deptExcel.setRoomTitle(dept.getRoom().getTitle());
                    }
                    return deptExcel;
                })
                .collect(Collectors.toList());
    }

}
